package com.zl.tby.core.base.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author changpeng
 * @version 1.0
 * @since 2025/4/20 18:36
 */
public enum DateTypeEnums {
    DAY("返回每天的数据", "create_date") {
        @Override
        public List<String> getXAxis(String startDate, String endDate) {
            Date start = ToolsUtil.dateString2Util(startDate, "yyyy-MM-dd");
            Date end = ToolsUtil.dateString2Util(endDate, "yyyy-MM-dd");
            return DateTypeEnums.getAllDatesBetween(start, end);
        }
    },
    MONTH("返回每月的数据", "create_month") {
        @Override
        public List<String> getXAxis(String startDate, String endDate) {
            Date start = ToolsUtil.dateString2Util(startDate, "yyyy-MM-dd");
            Date end = ToolsUtil.dateString2Util(endDate, "yyyy-MM-dd");
            return DateTypeEnums.getAllMonthsBetween(start, end);
        }
    },
    YEAR("返回每年的数据", "create_year") {
        @Override
        public List<String> getXAxis(String startDate, String endDate) {
            Date start = ToolsUtil.dateString2Util(startDate, "yyyy-MM-dd");
            Date end = ToolsUtil.dateString2Util(endDate, "yyyy-MM-dd");
            return DateTypeEnums.getAllYearsBetween(start, end);
        }
    };
    private String value;
    private String column;
    DateTypeEnums(String value, String column) {
        this.value = value;
        this.column = column;
    }

    public static DateTypeEnums getByCode(String code) {
        DateTypeEnums[] array = values();
        for (DateTypeEnums dateTypeEnums : array) {
            if (dateTypeEnums.toString().equals(code)) {
                return dateTypeEnums;
            }
        }
        return DAY;
    }

    public static DateTypeEnums getDateType(String beginTime, String endTime) {
        if (beginTime.indexOf(' ') < 0) {
            beginTime = beginTime + "  00:00:00";
        }
        if (endTime.indexOf(' ') < 0) {
            endTime = endTime + " 00:00:00";
        }
        Date fromDate = ToolsUtil.dateString2Util(beginTime, "yyyy-MM-dd HH:mm:ss");
        Date toDate = ToolsUtil.dateString2Util(endTime, "yyyy-MM-dd HH:mm:ss");
        int time = (int) ((toDate.getTime() - fromDate.getTime()) / (1000 * 3600 * 24));
        DateTypeEnums dateTypeEnums = DateTypeEnums.DAY;
        if (time > 31) {
            dateTypeEnums = DateTypeEnums.MONTH;
            time = ToolsUtil.getMonthDifference(fromDate, toDate);
            if (time > 12) {
                dateTypeEnums = DateTypeEnums.YEAR;
            }
        }
        return dateTypeEnums;
    }

    public abstract List<String> getXAxis(String startDate, String endDate);

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getColumn() {
        return column;
    }

    public void setColumn(String column) {
        this.column = column;
    }

    /**
     * 获取两个日期之间的所有日期
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 日期列表
     */
    public static List<String> getAllDatesBetween(Date startDate, Date endDate) {
        List<String> dateList = new ArrayList<>();

        // 确保开始日期早于或等于结束日期
        if (startDate.after(endDate)) {
            return dateList;
        }

        // 创建日期格式化对象，用于日期加减操作后的格式化
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        startDate = truncateToDay(startDate, sdf);
        endDate = truncateToDay(endDate, sdf);

        // 当前日期设置为开始日期
        Date currentDate = (Date) startDate.clone();

        // 循环直到当前日期等于结束日期
        while (!currentDate.after(endDate)) {
            dateList.add(sdf.format((Date) currentDate.clone()));
            // 当前日期加一天
            currentDate = addDays(currentDate, 1);
        }

        return dateList;
    }

    /**
     * 将日期截断到天（去除时间部分）
     *
     * @param date   日期
     * @param sdf    日期格式化对象
     * @return 截断后的日期
     */
    private static Date truncateToDay(Date date, SimpleDateFormat sdf) {
        try {
            return sdf.parse(sdf.format(date));
        } catch (ParseException e) {
            throw new RuntimeException("日期截断失败", e);
        }
    }

    /**
     * 日期加指定的天数
     *
     * @param date  日期
     * @param days  天数
     * @return 加天后的日期
     */
    private static Date addDays(Date date, int days) {
        long time = date.getTime();
        time += days * 24 * 60 * 60 * 1000L;
        return new Date(time);
    }

    /**
     * 获取两个日期之间的所有月份（简化版）
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 月份列表，格式为"yyyy-MM"
     */
    public static List<String> getAllMonthsBetween(Date startDate, Date endDate) {
        List<String> monthList = new ArrayList<>();

        // 确保开始日期早于或等于结束日期
        if (startDate.after(endDate)) {
            throw new IllegalArgumentException("开始日期不能晚于结束日期");
        }

        // 创建Calendar对象用于日期操作
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);

        // 格式化日期的SimpleDateFormat对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

        // 设置为开始日期的年份和月份的第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);

        // 循环直到当前月份或年份超过结束日期的月份或年份
        while (calendar.getTime().before(endDate) ||
                (calendar.getTime().equals(endDate) && calendar.get(Calendar.DAY_OF_MONTH) == 1)) {
            // 添加当前月份到列表
            monthList.add(sdf.format(calendar.getTime()));

            // 当前月份加一个月
            calendar.add(Calendar.MONTH, 1);
        }

        return monthList;
    }

    /**
     * 获取两个日期之间的所有年份
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 年份列表
     */
    public static List<String> getAllYearsBetween(Date startDate, Date endDate) {
        List<String> yearList = new ArrayList<>();

        // 确保开始日期早于或等于结束日期
        if (startDate.after(endDate)) {
            throw new IllegalArgumentException("开始日期不能晚于结束日期");
        }

        // 创建Calendar对象用于日期操作
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);

        // 获取开始年份和结束年份
        int startYear = calendar.get(Calendar.YEAR);
        calendar.setTime(endDate);
        int endYear = calendar.get(Calendar.YEAR);

        // 循环添加年份到列表
        for (int year = startYear; year <= endYear; year++) {
            yearList.add(year + "");
        }

        return yearList;
    }
}
